package com.lanyou.esb.cook.proxy.dao.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.time.DateFormatUtils;

import com.lanyou.esb.cook.proxy.common.DateUtils;
import com.lanyou.esb.cook.proxy.entity.AccLog;
import com.lanyou.esb.cook.proxy.exception.PersistentDataException;

/**
 * 服务日志持久层
 * 
 * @author Davey.wu
 */
public class AccLogDao extends BaseDao<AccLog> {
	private static final List<String> fields = new ArrayList<String>();

	/** 匹配模式 **/
	private static final String pattern = "MM";
	/** SQL开头 **/
	private static final String SQL_START = "insert into T_ESB_BU_ACCESS_LOG_M";
	/** SQL结尾 **/
	private static String SQL_END = "";
	static {
		fields.add("FIELD_ID");
		fields.add("FIELD_SYSTEM_ID");
		fields.add("IF_ID");
		fields.add("IF_TYPE");
		fields.add("IF_NAME");
		fields.add("IF_CALL_SYSTEM_ID");
		fields.add("REQUEST_IP");
		fields.add("IN_ESB_DATE");
		fields.add("OUT_ESB_DATE");
		fields.add("TOTAL_RESPONSE_TIMES");
		fields.add("PLATFORM_REQUEST_DATE");
		fields.add("PLATFORM_RESPONSE_DATE");
		fields.add("PLATFORM_TIMES");
		fields.add("REQUEST_RESULT");
		fields.add("REQUEST_RESULT_DESC");
		fields.add("THROUGHPUT_QTY");
		fields.add("IS_ENABLE");
		fields.add("CREATOR");
		fields.add("CREATED_DATE");
		fields.add("MODIFIER");
		fields.add("LAST_UPDATED_DATE");
	}
	static {
		StringBuilder builderFields = new StringBuilder();
		StringBuilder builderValues = new StringBuilder();
		builderFields.append(" (");
		builderValues.append(" (");
		int size = fields.size();
		for (int i = 0; i < size; ++i) {
			builderFields.append(fields.get(i) + (i == size - 1 ? "" : ","));
			builderValues.append((i == size - 1 ? "?" : "?,"));
		}
		builderFields.append(") ");
		builderValues.append(") ");
		SQL_END = builderFields.toString() + " values "
				+ builderValues.toString();
	}

	@Override
	public int save(final AccLog log) {
		String dd = DateFormatUtils.format(log.getCreatedDate(), pattern);
		String SQL = SQL_START + dd + SQL_END;

		return getJdbcTemplate().update(SQL, log.getFieldId(),
				log.getSystemId(), log.getIfId(), log.getIfType(),
				log.getIfName(), log.getCallSystemId(), log.getRequestId(),
				log.getInEsbDate() != null ? DateUtils.DATEPATTERN_YYYYMMDDHHMMssSSS
						.format(log.getInEsbDate()) : null, log.getOutEsbDate() != null ? DateUtils.DATEPATTERN_YYYYMMDDHHMMssSSS
								.format(log.getOutEsbDate()) : null,
				log.getTotalResTimes(), log.getPlatReqDate() != null ? DateUtils.DATEPATTERN_YYYYMMDDHHMMssSSS
						.format(log.getPlatReqDate()) : null,
						log.getPlatResDate() != null ? DateUtils.DATEPATTERN_YYYYMMDDHHMMssSSS
								.format(log.getPlatResDate()) : null, log.getPlatTimes(), log.getReqResult(),
				log.getReqResultDesc(), log.getThroughputQty(),
				log.getIsEnable(), log.getCreator(), log.getCreatedDate(),
				log.getModifier(), log.getLastUpdatedDate());

	}

	@Override
	public int saveAll(List<AccLog> logs) throws PersistentDataException {
		if (logs == null || logs.isEmpty()) {
			return 0;
		}

		// 对表进行按年月分组
		Map<String, List<AccLog>> map = new HashMap<>();
		for (AccLog log : logs) {
			String dd = DateFormatUtils.format(log.getInEsbDate(), pattern);
			List<AccLog> list = map.get(dd);
			if (list == null) {
				list = new ArrayList<>();
				map.put(dd, list);
			}
			list.add(log);
		}
		int num = 0;

		try {
			// 按组存储日志
			for (Entry<String, List<AccLog>> entry : map.entrySet()) {
				String yydd = entry.getKey();
				List<AccLog> list = entry.getValue();
				String SQL = SQL_START + yydd + SQL_END;
				int[] temp = addLogs(SQL, list);
				if (temp != null && temp.length > 0) {
					for (int i : temp) {
						num += i;
					}
				}
			}
		} catch (Exception e) {
			throw new PersistentDataException(e.getMessage());
		}
		return num;
	}

	private int[] addLogs(final String sql, List<AccLog> logs) {
		if (logs == null || logs.isEmpty()) {
			return new int[0];
		}
		final List<Object[]> args = new ArrayList<>();
		int i = 0;
		for (AccLog log : logs) {
			i = 0;
			Object[] objects = new Object[fields.size()];
			objects[i++] = log.getFieldId();
			objects[i++] = log.getSystemId();
			objects[i++] = log.getIfId();
			objects[i++] = log.getIfType();
			objects[i++] = log.getIfName();
			objects[i++] = log.getCallSystemId();
			objects[i++] = log.getRequestId();
			objects[i++] = log.getInEsbDate() != null ? DateUtils.DATEPATTERN_YYYYMMDDHHMMssSSS
					.format(log.getInEsbDate()) : null;
			objects[i++] = log.getOutEsbDate() != null ? DateUtils.DATEPATTERN_YYYYMMDDHHMMssSSS
					.format(log.getOutEsbDate()) : null;
			objects[i++] = log.getTotalResTimes();
			objects[i++] = log.getPlatReqDate() != null ? DateUtils.DATEPATTERN_YYYYMMDDHHMMssSSS
					.format(log.getPlatReqDate()) : null;
			objects[i++] = log.getPlatResDate() != null ? DateUtils.DATEPATTERN_YYYYMMDDHHMMssSSS
					.format(log.getPlatResDate()) : null;
			objects[i++] = log.getPlatTimes();
			objects[i++] = log.getReqResult();
			objects[i++] = log.getReqResultDesc();
			objects[i++] = log.getThroughputQty();
			objects[i++] = log.getIsEnable();
			objects[i++] = log.getCreator();
			objects[i++] = log.getCreatedDate();
			objects[i++] = log.getModifier();
			objects[i++] = log.getLastUpdatedDate();
			args.add(objects);
		}
		return getJdbcTemplate().batchUpdate(sql, args);
	}
}
